package com.cby.operation.login.data

import android.text.TextUtils
import com.cby.operation.common.http.HttpHelper
import com.cby.operation.common.util.CbyLogUtils
import com.cby.operation.common.util.HandlerUtils
import com.cby.operation.common.util.ThreadPoolUtils
import com.cby.operation.initialize.data.InitConfig
import com.cby.operation.sdk.*
import com.cby.operation.sdk.http.UrlHelper
import com.cby.operation.sdk.util.VerifyUtils
import org.json.JSONException
import org.json.JSONObject
import java.lang.ref.WeakReference
import java.util.*

/**
 * 登录相关的网络请求库
 */
object LoginApiRepository {

    private const val TAG = "Login"

    /**
     * 用户信息校验路径字段
     */
    private const val AUTH_PATH = "user/grant"

    /**
     * 用户信息校验接口
     */
    private val USER_VALID_URL = UrlHelper.buildSdkUrl(AUTH_PATH)

    /**
     * 对外校验码获取接口地址
     *
     * 测试环境地址：[http://t.newsapp.5054399.com/kuaibao/android/devsdk.php]
     * OT环境东西：[http://ot.newsapp.5054399.com/kuaibao/android/devsdk.php]
     * 正式环境地址：[https://api.3839app.com/kuaibao/android/devsdk.php]
     */
    private const val ACCESS_TOKEN_HOST = "https://api.3839app.com/kuaibao/android/devsdk.php"

    //请求数据的回调接口对象的，弱引用
    private lateinit var reference: WeakReference<OnLoginApiCallback>



    /**
     * 获取请求需要的参数，json形式
     *
     * @throws JSONException
     */
    @Throws(JSONException::class)
    private fun getJsonParam(appId: String, user: InternalUser): JSONObject {
        val jsonParam = JSONObject()
        jsonParam.put("c", "authgame")
        jsonParam.put("a", "getAccessToken")
        jsonParam.put("v", "1546")
        jsonParam.put("app_id", appId)
        jsonParam.put("uid", user.userId)
        jsonParam.put("type", user.loginType)
        jsonParam.put("user_token", user.token)
        return jsonParam
    }

    /**
     * 获取快爆用户校验码
     */
    @Throws(JSONException::class)
    private fun loadAccessToken(
        gameId: String,
        user: InternalUser
    ) {
        val jsonParam: JSONObject = getJsonParam(gameId, user)
        ThreadPoolUtils.execute {
            HttpHelper.requestPost(
                ACCESS_TOKEN_HOST,
                jsonParam,
                object : HttpHelper.OnHttpRequestListener {
                    override fun onResponseSuccess(response: String?) {
                        try {
                            CbyLogUtils.flog(TAG, response)
                            if (!TextUtils.isEmpty(response)) {
                                val data = JSONObject(response)
                                val code = data.optInt(KEY_RESPONSE_CODE)
                                val resultJson =
                                    data.optJSONObject(KEY_RESPONSE_RESULT)
                                if (code == 100) {
                                    val accessToken = resultJson.optString(KEY_RESPONSE_ACCESS_TOKEN)
                                    user.accessToken = accessToken
                                    CbyLogUtils.flog("accessToken = $accessToken")
                                }
                            }
                        } catch (e: Exception) {
                            CbyLogUtils.flog(TAG, "errorMessage=" + e.message)
                        }
                        HandlerUtils.runOnMainThread { handleOnUserCheckSucceed() }
                    }

                    override fun onResponseError(code: Int, errorMessage: String?) {
                        CbyLogUtils.e(TAG, "error=$code, errorMessage=$errorMessage")
                        HandlerUtils.runOnMainThread{ handleOnUserCheckSucceed() }
                    }
                })
        }
    }


    /**
     * 原创平台的用户信息的校验
     *
     * @param gameId
     * @param user
     * @param callback
     * @throws JSONException
     */
    @Throws(JSONException::class)
    fun authCheck(
        gameId: String,
        user: InternalUser?,
        callback: OnLoginApiCallback?
    ) {
        reference = WeakReference(callback)
        ThreadPoolUtils.execute{
            val timeStamp = System.currentTimeMillis()
            val sign: String = VerifyUtils.getVerifySign(
                gameId,
                user!!.userId,
                AUTH_PATH,
                timeStamp.toString()
            )
            val jsonParam: MutableMap<String, Any> = HashMap()
            jsonParam[KEY_GAME_ID] = gameId
            jsonParam[KEY_TIME_STAMP] = timeStamp
            jsonParam[KEY_SIGN] = sign

            HttpHelper.requestPost(USER_VALID_URL,
                jsonParam,
                UrlHelper.authHeaders,
                object : HttpHelper.OnHttpRequestListener {
                    override fun onResponseSuccess(response: String?) {
                        try {
                            if (TextUtils.isEmpty(response)) {
                                onResponseError(
                                    ERR_CODE_SERVER_EXCEPTION,
                                    ERR_MSG_SERVER_EXCEPTION
                                )
                                return
                            }
                            parseUserJson(response, gameId, user)
                        } catch (e: JSONException) {
                            onResponseError(ERR_CODE_SERVER_EXCEPTION, e.message)
                        }
                    }

                    override fun onResponseError(code: Int, errorMessage: String?) {
                        CbyLogUtils.flog(TAG, errorMessage)
                        HandlerUtils.runOnMainThread {
                            handleOnUserCheckFailed(code, errorMessage)
                        }
                    }
                })
        }
    }

    /**
     * 解析用户校验的结果
     *
     * @param response
     * @param callback
     * @throws JSONException
     */
    @Throws(JSONException::class)
    private fun parseUserJson(
        response: String?,
        gameId: String,
        user: InternalUser
    ) {
        val data = JSONObject(response)
        val code = data.optInt(KEY_RESPONSE_CODE)
        val msg = data.optString(KEY_RESPONSE_MSG)
        val dataJson = data.optJSONObject(KEY_RESPONSE_DATA)
        when (code) {
            CODE_SUCCESS -> loadAccessToken(
                gameId,
                user
            )
            CODE_USER_BANNED -> {
                //显示账号被封禁的对话框
                val tip = InternalTip(
                    tipContent = dataJson.optString(KEY_CONTENT),
                    negativeBtnName = STRING_EXIT_GAME,
                    negativeBtnAction = ACTION_TIP_NEGATIVE_EXIT_GAME,
                    positiveBtnName = STRING_SWITCH_ACCOUNT,
                    positiveBtnAction = ACTION_TIP_POSITIVE_SWITCH_ACCOUNT
                )
                HandlerUtils.runOnMainThread { handleOnUserBanned(code, tip) }
            }
            CODE_USER_ROBBED -> {
                //code : 2003 表示用户被抢登
                val tip2 = InternalTip(
                    tipContent = msg,
                    negativeBtnName = STRING_EXIT_GAME,
                    negativeBtnAction = ACTION_TIP_NEGATIVE_EXIT_GAME,
                    positiveBtnName = STRING_LOGIN_AGAIN,
                    positiveBtnAction = ACTION_TIP_POSITIVE_LOGIN_AGAIN
                )
                HandlerUtils.runOnMainThread { handleOnUserBanned(code, tip2) }
            }
            else ->
                //默认都是校验失败
                handleOnUserCheckFailed(code, msg)
        }
    }

    /**
     * 处理接口用户信息校验成功的回调
     */
    private fun handleOnUserCheckSucceed() {
        reference.get()?.onUserCheckSucceed()
    }

    /**
     *  处理接口用户信息校验失败的回调
     *
     * @param code Int
     * @param msg String?
     */
    private fun handleOnUserCheckFailed(code: Int, msg: String?) {
        reference.get()?.onUserCheckFailed(code, msg)
    }

    /**
     * 处理接口初始化返回游戏维护的回调
     *
     * @param config InitConfig? [InitConfig]
     */
    private fun handleOnUserBanned(code: Int, tip: InternalTip) {
        reference.get()?.onUserBanned(code, tip)
    }

    /**
     * 用户api处理接口
     */
    interface OnLoginApiCallback {
        /**
         * 用户校验成功回调
         */
        fun onUserCheckSucceed()

        /**
         * 用户校验失败
         *
         * @param code
         * @param msg
         */
        fun onUserCheckFailed(code: Int, msg: String?)

        /**
         * 用户被禁回调
         *
         * @param code
         * @param tip
         */
        fun onUserBanned(code: Int, tip: InternalTip)
    }

}